package com.xw.bo.ks.generator;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ServiceCodeGenerator {


    public static String tableName = "user_register_info1";

    public static String className = "UserRegisterInfo1"; // e.g., User

    public static String basePackageName = "com.xw.bo.ks."; // e.g.

    public static String baseLineName = "/com/xw/bo/ks"; // e.g.

    public static String packageName = basePackageName + "service";

    public static Map<String, Object> dataModelMap = new HashMap<>();


    public static void main(String[] args) throws IOException, TemplateException, SQLException {

        // Load fields metadata from database (reuse previous method)
        List<Map<String, String>> fields = TableMetadata.getTableMetadata(tableName);

        // Initialize FreeMarker configuration
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
        cfg.setClassForTemplateLoading(ServiceCodeGenerator.class, "/templates");

        // Load Service template
//        Template template = cfg.getTemplate("ServiceClass.ftl");
//        Template templateImpl = cfg.getTemplate("ServiceClassImpl.ftl");
//        Template templateMapper = cfg.getTemplate("Mapper.ftl");
//        Template templateController = cfg.getTemplate("ControllerClass.ftl");
//        Template templateClass = cfg.getTemplate("EntityClass.ftl");
//        Template templateReq = cfg.getTemplate("EntityReqClass.ftl");

        // Prepare data model
        Map<String, Object> dataModel = new HashMap<>();
        dataModel.put("packageName", packageName);
        dataModel.put("tableName", tableName);
        dataModel.put("basePackageName", basePackageName);
        dataModel.put("className", className);

        // 时间范围查询的字段
        dataModel.put("fieldTime", "createdAt");
        dataModel.put("fieldOrderBy", "createdAt");

        // mapper.xml的需要字段
        dataModel.put("fieldTableTime", "created_at");
        dataModel.put("fieldTableOrderBy", "created_at");

        dataModel.put("fields", fields);
        dataModelMap = dataModel;

        qoModel(cfg);

        classModel(cfg);

//        classUnderlineModel(cfg);

        mapperModel(cfg);

        mapperXmlModel(cfg);

        reqModel(cfg);

        serviceModel(cfg);

        serviceImplModel(cfg);

        controllerModel(cfg);

        controllerTestModel(cfg);

        serviceImplTestModel(cfg);
    }


    public static void classModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("EntityClass.ftl");

        Map<String, Object> classModel = new HashMap<>(dataModelMap);
        classModel.put("packageName", basePackageName+"entity");
        String outputPathClass = "src/main/java"+baseLineName+"/entity/"+ className +".java";

        process(template,classModel,outputPathClass);
    }

    public static void classUnderlineModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("EntityUnderlineClass.ftl");

        Map<String, Object> classModel = new HashMap<>(dataModelMap);
        classModel.put("packageName", basePackageName+"entity");
        String outputPathClass = "src/main/java"+baseLineName+"/entity/"+ className +".java";

        process(template,classModel,outputPathClass);
    }

    public static void mapperXmlModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("MapperXml.ftl");

        Map<String, Object> mapperModel = new HashMap<>(dataModelMap);
        mapperModel.put("packageName", basePackageName+"mapper");
        String outputPathMapper = "src/main/resources/mapper/" + className + "Mapper.xml";

        process(template,mapperModel,outputPathMapper);
    }

    public static void mapperModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("Mapper.ftl");

        Map<String, Object> mapperModel = new HashMap<>(dataModelMap);
        mapperModel.put("packageName", basePackageName+"mapper");
        String outputPathMapper = "src/main/java"+baseLineName+"/mapper/" + className + "Mapper.java";

        process(template,mapperModel,outputPathMapper);
    }

    public static void qoModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("EntityQoClass.ftl");

        Map<String, Object> reqModel = new HashMap<>(dataModelMap);
        reqModel.put("packageName", basePackageName+"entity.bean");
        String reqMapper = "src/main/java"+baseLineName+"/entity/bean/" + className + "Qo.java";

        process(template,reqModel,reqMapper);
    }

    public static void reqModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("EntityReqClass.ftl");

        Map<String, Object> reqModel = new HashMap<>(dataModelMap);
        reqModel.put("packageName", basePackageName+"entity.bean");
        String reqMapper = "src/main/java"+baseLineName+"/entity/bean/" + className + "Req.java";

        process(template,reqModel,reqMapper);
    }

    public static void serviceModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("ServiceClass.ftl");

        String outputPath = "src/main/java"+baseLineName+"/service/" + className + "Service.java";
        process(template,dataModelMap,outputPath);
    }

    public static void serviceImplModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("ServiceClassImpl.ftl");

        String outputPathImpl = "src/main/java"+baseLineName+"/service/impl/" + className + "ServiceImpl.java";
        process(template,dataModelMap,outputPathImpl);
    }

    public static void serviceImplTestModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("ServiceClassImplTest.ftl");

        String outputPathImpl = "src/test/java"+baseLineName+"/service/" + className + "ServiceImplTest.java";
        process(template,dataModelMap,outputPathImpl);
    }

    public static void controllerModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("ControllerClass.ftl");

        Map<String, Object> controllerModel = new HashMap<>(dataModelMap);
        controllerModel.put("packageName", basePackageName+"controller");
        String outputPathController = "src/main/java"+baseLineName+"/controller/" + className + "Controller.java";

        process(template,controllerModel,outputPathController);
    }

    public static void controllerTestModel(Configuration cfg) throws IOException, TemplateException {
        Template template = cfg.getTemplate("ControllerClassTest2.ftl");

        Map<String, Object> controllerModel = new HashMap<>(dataModelMap);
        controllerModel.put("packageName", basePackageName+"controller");
        String outputPathController = "src/test/java"+baseLineName+"/controller/" + className + "ControllerTest.java";

        process(template,controllerModel,outputPathController);
    }


    public static void process(Template template,Map<String, Object> dataModel,String outputPath) throws IOException, TemplateException {
        try (Writer out = new FileWriter(outputPath)) {
            template.process(dataModel, out);
        }
    }

}
